#pragma once
#include "Vertex.hpp"
#include "Octree.h"
#include "Primitives/SortPrimitive.h"
#include "Primitives/ScanPrimitive.h"
#include "Primitives/CompactPrimitive.h"
#include "QD3D/QD3DResourcePack.h"
#include "QD3D/QD3DUtils.h"
#include <d3d11.h>
#include <QVector>
#include <glm/glm.hpp>


class OctreeConstructor
{
public:

	CONST_STRUCT_BEGIN(MainIdxHint)
		UINT mainIdx;
	CONST_STRUCT_END

	OctreeConstructor ();
	~OctreeConstructor ();

	void initial (Octree *p_octree);
	void process (Octree *p_octree, QD3DResourcePack *p_verticesPack);
	void clean ();
	void clearOctree (Octree *p_octree);

private:

// 	UINT _elemNum;
	QD3DResourcePack *_rp_verticesPack;
	Octree *_rp_octree;


	ID3D11Buffer *_p_mainIdxHintDxConstBuf;

	QD3DResourcePack *_p_emptyKeysPack;
	QD3DResourcePack *_p_emptyMarksPack;
	QD3DResourcePack *_p_emptyNodesPack;


	QD3DResourcePack *_p_infoPack;
	QD3DResourcePack *_p_tablePack;

	QD3DResourcePack *_p_unsortedKeysPack;
	QD3DResourcePack *_p_keysPack;
	QD3DResourcePack *_p_compactedKeysPack;
	QD3DResourcePack *_p_marksPack;
	QD3DResourcePack *_p_nodesPack;
	QD3DResourcePack *_p_addrsPack;

	SortPrimitive *_p_sortPrimitive;
	CompactPrimitive *_p_compactPrimitive;

	ID3D11ComputeShader *_p_updateInfoInConstructNodesCS;
	ID3D11ComputeShader *_p_calcKeyCS;
	ID3D11ComputeShader *_p_genSortedVerticesAndKeysCS;
	ID3D11ComputeShader *_p_markUniqueCS;
	ID3D11ComputeShader *_p_genNodesAndMarkUniqueParentCS;
	ID3D11ComputeShader *_p_adjustAddrsAndUpdateKeysCS;
	ID3D11ComputeShader *_p_fillFinalNodesCS;
	ID3D11ComputeShader *_p_connectParentChildrenCS;

	ID3D11ComputeShader *_p_updateInfoInConnectNeighborsCS;
	ID3D11ComputeShader *_p_connectRootNeighborsCS;
	ID3D11ComputeShader *_p_connectNeighborsCS;

	ID3D11ComputeShader *_p_genNodeVerticesCS;
	ID3D11ComputeShader *_p_genNodeEdgesCS;

	ID3D11ComputeShader *_p_clearOctreeNodesCS;
	ID3D11ComputeShader *_p_clearOctreeNodeVerticesCS;
	ID3D11ComputeShader *_p_clearOctreeNodeEdgesCS;


	void _updateInfoInConstructNodes ();
	void _generateKeys ();
	void _sortKeysAndVertices ();
	void _markUnique ();
	void _compactKeys ();
	void _adjustAddrsAndUpdateKeys ();
	void _genNodesAndMarkUniqueParent ();
	void _fillFinalNodes ();
	void _connectParentChildren ();
	void _resetBufs ();

	void _updateInfoInConnectNeighbors ();
	void _connectNeighbors ();
	void _connectRootNeighbors ();

	void _genNodeVertices ();
	void _genNodeEdges ();
};

